// eventbus
package eventbus

import "context"

var defaultEventBus Eventbus

func init() {
	defaultTypeEventHub = NewTypeEventHub()
	defaultEventBus = NewTypeEventBus(defaultTypeEventHub)
}
func fire(ctx context.Context, event interface{}) {
	defaultEventBus.fire(ctx, event)
}
func fireAsync(ctx context.Context, event interface{}) {
	defaultEventBus.fireAsync(ctx, event)
}

type Eventbus interface {
	// 触发一个事件，并提供执行上下文
	fire(ctx context.Context, event interface{})
	// 异步触发一个事件，并提供执行上下文
	fireAsync(ctx context.Context, event interface{})
}

// 使用参数类型来实现的eventbus
type typeEventBus struct {
	hub *TypeEventHub
}

// 返回一个按类型注册的
func NewTypeEventBus(hub *TypeEventHub) Eventbus {
	var bus Eventbus = &typeEventBus{
		hub: hub,
	}
	return bus
}

// 触发事件
func (bus *typeEventBus) fire(ctx context.Context, event interface{}) {
	handlers, ok := bus.hub.GetHandlers(event)
	if ok {
		for _, handler := range handlers {
			handler.invoke(ctx, event)
		}
	}
}

// 异步触发事件
func (bus *typeEventBus) fireAsync(ctx context.Context, event interface{}) {
	handlers, ok := bus.hub.GetHandlers(event)
	if ok {
		for _, handler := range handlers {
			go func(ctx context.Context, event interface{}) {
				handler.invoke(ctx, event)
			}(ctx, event)
		}
	}
}
